package httpUtil

import (
	"app/pkg/log"
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	Faild_404 = "error http code 404"
)

func SimpleGet(url string) (response []byte, err error) {
	client := http.Client{Timeout: 5 * time.Second}
	resp, err := client.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	log.NewInfo("request get", fmt.Sprintf("url %s, resp %+v", url, string(body)))
	if err != nil {
		return nil, err
	}
	return body, nil
}

func Get(url string, headers map[string]string, timeOutSecond int) (response []byte, err error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Close = true
	// req.Header.Add("Content-Type", "application/json; charset=utf-8")
	if len(headers) > 0 {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	//跳过tls
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	//http cookie接口
	cookieJar, _ := cookiejar.New(nil)
	client := &http.Client{Transport: tr, Jar: cookieJar, Timeout: time.Duration(timeOutSecond) * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		if resp.StatusCode == 429 {
			//接口被限制
			return nil, fmt.Errorf("error http code %d", resp.StatusCode)
		}
		return nil, fmt.Errorf("error http code %d", resp.StatusCode)
	}
	result, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return result, nil
}

func JsonPost(url string, data interface{}, headers map[string]string, timeOutSecond int) (content []byte, err error) {
	jsonStr, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	if err != nil {
		return nil, err
	}
	req.Close = true
	_, ok := headers["Content-Type"]
	if !ok {
		req.Header.Set("Content-Type", "application/json; charset=utf-8")
	}
	if len(headers) > 0 {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	//跳过tls
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr, Timeout: time.Duration(timeOutSecond) * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		err = errors.New(resp.Status)
	}
	defer resp.Body.Close()
	result, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return result, err
}

func Post(postUrl string, data map[string]string, headers map[string]string, timeOutSecond int) (content []byte, err error) {
	vals := url.Values{}
	for k, v := range data {
		vals.Add(k, v)
	}
	req, err := http.NewRequest("POST", postUrl, strings.NewReader(vals.Encode()))
	if err != nil {
		return nil, err
	}
	req.Close = true
	if len(headers) > 0 {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	_, ok := headers["Content-Type"]
	if !ok {
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}
	//跳过tls
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr, Timeout: time.Duration(timeOutSecond) * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		return nil, fmt.Errorf(resp.Status)
	}
	defer resp.Body.Close()
	result, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// 获取远程文件的大小
func GetSizeByHeader(url string) (bytes int) {
	resp, err := http.Head(url)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	length := resp.Header.Get("Content-Length")
	bytes, _ = strconv.Atoi(length)
	return
}
